/**************************************************************************** 
 * Meta，一个轻量级的静态分区Hypervisor 
 *
 * 版权(c) , 2022-
 *
 * 作者:
 *      Tupelo Shen <shenwanjiang2013@163.com>
 *
 * Meta是一个自由软件，你可以在遵循GNU GPLv2协议的条件下，重新修改并发布它。
 *
 ***************************************************************************/

#include <iommu.h>
#include <vm.h>

/* 设备数据结构 */
struct iommu_device {
    streamid_t id;
};

/* 设备节点数据结构 */
struct iommu_dev_node {
    node_t node;
    struct iommu_device dev;
};

/****************************************************************************
 ****                           公共函数定义                             ****
 ****************************************************************************/
/**
 * 功能描述: IO内存初始化，主要是完成硬件初始化
 * 入口参数: void
 * 出口参数: void
 * 返 回 值: void
 * 修改日期: 2022-09-21
 */
void iommu_init()
{
    iommu_arch_init();
}

/**
 * 功能描述: 配置与架构相关的设置
 * 入口参数: vm,        虚拟机的所有信息
 *           config,    虚拟机的配置信息       
 * 出口参数: void
 * 返 回 值: int,       成功返回0   
 * 修改日期: 2022-09-21
 */
bool iommu_vm_init(struct vm *vm, const struct vm_config *config)
{
    objcache_init(&vm->iommu.dev_oc, sizeof(struct iommu_dev_node),
                  SEC_HYP_GLOBAL, false);

    return iommu_arch_vm_init(vm, config);
}

/**
 * 功能描述: 允许VM添加设备到自己的地址空间中
 * 入口参数: vm,        虚拟机的所有信息
 *           dev_id,    设备标识符       
 * 出口参数: void
 * 返 回 值: int,       成功返回0   
 * 修改日期: 2022-09-21
 */
bool iommu_vm_add_device(struct vm *vm, streamid_t dev_id)
{
    bool res = false;

    /**
     * 如果dev_id == 0，则为该VM屏蔽掉该外设
     *
     * 我们假设没有设备的ID等于0
     */
    if (dev_id != 0) {

        /* 设备ID合法，匹配是否为该虚拟机的设备，然后添加 */
        res = iommu_arch_vm_add_device(vm, dev_id);
    }

    if (res) {
        struct iommu_dev_node *ptr = objcache_alloc(&vm->iommu.dev_oc);
        if(ptr != NULL){
            ptr->dev.id = dev_id;
            list_push(&vm->iommu.dev_list, (node_t *)ptr);
        } else {
            res = false;
        }
    }

    return res;
}